/**
 * This class listens to the client requests from FrontEnd or
 * leader in data UDP port.
 */
package com.comp6231.coordinator;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

import com.comp6231.common.Request;
import com.comp6231.common.Log;
import com.comp6231.replica1.exception.LogOperationException;

/**
 * @author Farzana Alam
 * 
 */
public class DataUDPServer implements Runnable {
	private Coordinator myCoordinator;

	public DataUDPServer(Coordinator coordinator) {
		super();
		this.myCoordinator = coordinator;
	}

	@Override
	public void run() {
		DatagramSocket socket = null;
		try {
			socket = new DatagramSocket(myCoordinator.myDataUDPPort);
			byte[] buffer;
			System.out.println("UDP server for data channel @"
					+ myCoordinator.myReplicaName + " is running on: "
					+ myCoordinator.myDataUDPPort);

			while (true) {
				buffer = new byte[10000];
				DatagramPacket packet = new DatagramPacket(buffer,
						buffer.length);
				socket.receive(packet);

				System.out.println("\nDataUDPServer received Packet: "
						+ new String(packet.getData()).trim());

				// Request object created
				Request request = new Request(packet);

				String replyMessage = myCoordinator.processRequest(request);

				System.out.println("DataUDPServer sending response: "
						+ replyMessage);

				// log the creation of the record
				Log log;
				try {
					log = new Log(System.getProperty("user.dir")
							+ "/src/com/comp6231/coordinator/logs/"
							+ myCoordinator.myReplicaName + ".txt",
							"Received Request ID " + request.getRequestID()
									+ " to perform the operation "
									+ request.getOperation(),
							request.getEntityName(), "Sending Reply: "
									+ replyMessage);
					log.save();
				} catch (LogOperationException e) {
					System.out.println("Log Operation Exception occurred.");
				}

				DatagramPacket reply = new DatagramPacket(
						replyMessage.getBytes(), replyMessage.length(),
						packet.getAddress(), packet.getPort());
				socket.send(reply);
				System.out.println("Request handled and out from "
						+ myCoordinator.myReplicaName + " : "
						+ request.getRequestID());
			}

		} catch (SocketException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (socket != null)
				socket.close();
		}

	}
}
